<?php

namespace System\library\utility;

use System\InitSystem;

/**
 * <b>Class</b> :        Tools<br>
 * <b>Fonction</b> :     Methodes utilitaires
 * <br>
 * @version              1.0
 * @author               Dread <dreadlokeur@gmail.com>
 * @license              Licence publique générale GNU http://www.gnu.org/licenses/gpl.html
 * @copyright            Copyright 2011 - MidichloriansPHP and contributors
 * @package              System
 * @subpackage           library\utility
 */
class Tools {

    /**
     * Compare the current PHP version to another
     *
     * @access public
     * @static
     * @param string $version php version
     * @return int  -1 if $version > current, 0 if equal, 1 if $version < current
     */
    public static function phpVersionCompareTo($version) {
        return version_compare(PHP_VERSION, $version);
    }

    /**
     * Convert a string to url format for url rewrite
     * 
     * @access public
     * @static
     * @param string $string String to encode
     * @param string $separator Separator for replacing space and ponctuation, by default "_"
     * @param string $encoding Set the encoding of source string, by default method get encoding of class MbString
     * @return string
     */
    public static function stringToUrl($string, $separator = '_', $encoding = null) {
        if ($encoding === null)
            $encoding = InitSystem::getCharset();
        $string = strtolower(htmlentities(html_entity_decode($string, null, $encoding), ENT_NOQUOTES, $encoding));
        $search = array('#\&(.)(?:uml|circ|tilde|acute|grave|cedil|ring)\;#', '#\&(.{2})(?:lig)\;#', '#\&[a-z]+\;#', '#[^a-zA-Z0-9_]#', '#' . $separator . '+#');
        $replace = array('\1', '\1', '', $separator, $separator);
        return trim(preg_replace($search, $replace, $string), $separator);
    }

    /**
     * Permet de selectionner un string dans une chaine en délimitant le début et la fin de la selection
     *
     * @access public
     * @static
     * @param string $haystack: la chaine dans laquelle la selection sera faite
     * @param string $delimiter_start: le début de la selection
     * @param string $delimiter_end: la fin de la selection
     * @return string la selection
     *
     * @example: $haystack = 'abcdefghij'; Utils::selectStringByDelimiter($haystack, 'b', 'g'); retourne 'bcdefg';
     */
    public static function selectStringByDelimiter($haystack, $delimiter_start, $delimiter_end) {
        $pos1 = strpos($haystack, $delimiter_start);
        if ($pos1 === false)
            throw new \Exception('Impossible de selectionner le string dans la chaine demander car le délimiter de début "' . $delimiter_start . '" n\'exsite pas');
        $pos2 = strpos($haystack, $delimiter_end, $pos1);
        if ($pos2 === false)
            throw new \Exception('Impossible de selectionner le string dans la chaine demander car le délimiter de fin "' . $delimiter_end . '" n\'exsite pas');

        return substr($haystack, $pos1, $pos2 - $pos1 + strlen($delimiter_end));
    }

    /**
     * Transforme un object en array
     *
     * @access public
     * @static
     * @param string $object : un objet
     * @return array $array
     */
    public static function parseObjectToArray($object) {
        $array = array();
        if (is_object($object))
            $array = get_object_vars($object);
        elseif (is_array($object)) {
            foreach ($object as $k => &$value)
                $array[$k] = self::parseObjectToArray($value);
        }else
            $array = $object;

        return $array;
    }

    /**
     * Permet de regarder si un fichier existe, depuis une url avec curl
     *
     * @access public
     * @static
     * @param string $url l'url
     * @return bool
     */
    public static function httpFileExistsWithCurl($url) {
        return ($ch = curl_init($url)) ? @curl_close($ch) || true : false;
    }

    /**
     * Permet de regarder si un fichier existe, depuis une url avec file_fet_contents
     *
     * @access public
     * @static
     * @param string $url l'url
     * @return bool
     */
    public static function httpFileExists($url) {
        return (@file_get_contents($url)) ? true : false;
    }

    /**
     * Permet de sauvegarder une fichier dans un répertoire, engendre une exception si la copy echoue
     *
     * @access public
     * @static
     * @param string $file fichier à sauvegarder
     * @param string $destination emplacement de sauvegarde
     * @param string $context une ressource de contexte (stream_context_create())
     * @return void
     *
     * TODO add ecrase file or not and check if file exist...
     */
    public static function saveFile($file, $destination, $context = null) {
        if (!copy($file, $destination, $context))
            throw new \Exception('La copie du fichier: ' . $file . ' a échoué...');
    }

    /**
     * Permet d'obtenir l'ip du client
     *
     * @access public
     * @static
     * @param void
     * @return string $ip user ip
     */
    public static function getUserIp() {
        if (isset($_SERVER['HTTP_X_FORWARDED_FOR']))
            $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
        elseif (isset($_SERVER['HTTP_CLIENT_IP']))
            $ip = $_SERVER['HTTP_CLIENT_IP'];
        else
            $ip = $_SERVER['REMOTE_ADDR'];

        return $ip;
    }

    /**
     * Permet de lister les repertoires d'un dossier
     *
     * @access public
     * @static
     * @param string $dir le dossier à parcourir
     * @return array $l: liste des dossiers dans le dossier
     *
     */
    public static function dirList($dir) {
        if (!is_dir($dir))
            throw new \Exception('"' . $dir . '" is not a valid directory');

        $l = array();
        foreach (self::cleanScandir($dir) as $f) {
            if (is_dir($dir . $f)) {
                $l[] = $dir . $f . '/';
                $l = array_merge($l, self::dirList($dir . $f . DIRECTORY_SEPARATOR));
            }
        }
        return $l;
    }

    /**
     * Permet de retourner le contenu d'un fichier inclut
     *
     * @access public
     * @static
     * @param string $filename le fichier à inclure
     * @param array $param_contents les paramètres pour l'inclusion du fichier: sous forme d'array: array(array('param_name' => 'var1', 'param_value' => 'test1'), array('param_name' => 'var2', 'param_value' => 'test2'))
     *              permet d'etablir les variables: $var1 et $var2 dans le fichier à inclure
     *              (OPTIONNEL)
     * @return string le contenu du fichier
     */
    public static function getIncludeContents($filename, $param_content = false) {
        //On verifie que le fichier existe, qu'il soit valid (lisible...) si ce n'est pas le cas, on genere une exception
        if (!is_file($filename) && !file_exists($filename) && !is_readable($filename))
            throw new \Exception('Le fichier "' . $filename . '" n\'existe pas ou est invalid');
        //Attribution du nom et valeur de variables contenu dans le fichier à inclure
        if ($param_contents) {
            for ($i = 0; $i < count($param_contents); $i++) {
                if (array_key_exists('param_name', $param_contents) && array_key_exists('param_value', $param_contents))
                    ${$param_contents[$i]['param_name']} = $param_contents[$i]['param_value'];
            }
        }
        ob_start();
        require $filename;
        $contents = ob_get_contents();
        ob_end_clean();
        return $contents;
    }

    /**
     * Permet scanner un dossier en enlevent les dossier ., .. et .svn du scandir()
     *
     * @access public
     * @static
     * @param string $dir le dossier à scanner
     * @return array le dossier scanné
     */
    public static function cleanScandir($dir) {
        if (!is_dir($dir))
            throw new \Exception('Impossible de scanner le dossier "' . $dir . ', il n\'existe pas');
        return array_diff(scandir($dir), array('.', '..', '.svn'));
    }
}

?>
